home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Tool Chest / Development Tools & Languages / • Other Platforms / PCCTS 1.31 / h / ASTBase.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-10  |  5.0 KB  |  185 lines  |  [TEXT/MPS ]

  1. /* Abstract syntax tree manipulation functions
  2.  *
  3.  * SOFTWARE RIGHTS
  4.  *
  5.  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
  6.  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
  7.  * company may do whatever they wish with source code distributed with
  8.  * PCCTS or the code generated by PCCTS, including the incorporation of
  9.  * PCCTS, or its output, into commerical software.
  10.  * 
  11.  * We encourage users to develop software with PCCTS.  However, we do ask
  12.  * that credit is given to us for developing PCCTS.  By "credit",
  13.  * we mean that if you incorporate our source code into one of your
  14.  * programs (commercial product, research project, or otherwise) that you
  15.  * acknowledge this fact somewhere in the documentation, research report,
  16.  * etc...  If you like PCCTS and have developed a nice tool with the
  17.  * output, please mention that you developed it using PCCTS.  In
  18.  * addition, we ask that this header remain intact in our source code.
  19.  * As long as these guidelines are kept, we expect to continue enhancing
  20.  * this system and expect to make other tools available as they are
  21.  * completed.
  22.  *
  23.  * ANTLR 1.31
  24.  * Terence Parr
  25.  * Parr Research Corporation
  26.  * with Purdue University and AHPCRC, University of Minnesota
  27.  * 1989-1995
  28.  */
  29. #include <stdio.h>
  30. #include <stdarg.h>
  31. #include "ASTBase.h"
  32.  
  33. /* ensure that tree manipulation variables are current after a rule
  34.  * reference
  35.  */
  36. void
  37. ASTBase::link(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail)
  38. {
  39.     if ( *_sibling == NULL ) return;
  40.     if ( *_root == NULL ) *_root = *_sibling;
  41.     else if ( *_root != *_sibling ) (*_root)->_down = *_sibling;
  42.     if ( *_tail==NULL ) *_tail = *_sibling;
  43.     while ( (*_tail)->_right != NULL ) *_tail = (*_tail)->_right;
  44. }
  45.  
  46. /* add a child node to the current sibling list */
  47. void
  48. ASTBase::subchild(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail)
  49. {
  50.     if ( *_tail != NULL ) (*_tail)->_right = this;
  51.     else {
  52.         *_sibling = this;
  53.         if ( *_root != NULL ) (*_root)->_down = *_sibling;
  54.     }
  55.     *_tail = this;
  56.     if ( *_root == NULL ) *_root = *_sibling;
  57. }
  58.  
  59. /* make a new AST node.  Make the newly-created
  60.  * node the root for the current sibling list.  If a root node already
  61.  * exists, make the newly-created node the root of the current root.
  62.  */
  63. void
  64. ASTBase::subroot(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail)
  65. {
  66.     if ( *_root != NULL )
  67.         if ( (*_root)->_down == *_sibling ) *_sibling = *_tail = *_root;
  68.     *_root = this;
  69.     (*_root)->_down = *_sibling;
  70. }
  71.  
  72. /* Apply preorder_action(), etc.. to root then each sibling */
  73. void
  74. ASTBase::preorder()
  75. {
  76.     ASTBase *tree = this;
  77.  
  78.     while ( tree!= NULL )
  79.     {
  80.         if ( tree->_down != NULL ) preorder_before_action();
  81.         tree->preorder_action();
  82.         if ( tree->_down!=NULL )
  83.         {
  84.             tree->_down->preorder();
  85.             preorder_after_action();
  86.         }
  87.         tree = tree->_right;
  88.     }
  89. }
  90.  
  91. /* free all AST nodes in tree; apply func to each before freeing */
  92. void
  93. ASTBase::destroy()
  94. {
  95.    ASTBase* tree = this;
  96.    while (tree) {
  97.       if (tree->_down) tree->_down->destroy();
  98.       
  99.       ASTBase* cur = tree;
  100.       tree = tree->_right;
  101.       delete cur;
  102.    }
  103. }
  104.  
  105. /* build a tree (root child1 child2 ... NULL)
  106.  * If root is NULL, simply make the children siblings and return ptr
  107.  * to 1st sibling (child1).  If root is not single node, return NULL.
  108.  *
  109.  * Siblings that are actually siblins lists themselves are handled
  110.  * correctly.  For example #( NULL, #( NULL, A, B, C), D) results
  111.  * in the tree ( NULL A B C D ).
  112.  *
  113.  * Requires at least two parameters with the last one being NULL.  If
  114.  * both are NULL, return NULL.
  115.  */
  116. ASTBase *
  117. ASTBase::tmake(ASTBase *root, ...)
  118. {
  119.     va_list ap;
  120.     register ASTBase *child, *sibling=NULL, *tail, *w;
  121.  
  122.     va_start(ap, root);
  123.  
  124.     if ( root != NULL )
  125.         if ( root->_down != NULL ) return NULL;
  126.     child = va_arg(ap, ASTBase *);
  127.     while ( child != NULL )
  128.     {
  129.         for (w=child; w->_right!=NULL; w=w->_right) {;} /* find end of child */
  130.         if ( sibling == NULL ) {sibling = child; tail = w;}
  131.         else {tail->_right = child; tail = w;}
  132.         child = va_arg(ap, ASTBase *);
  133.     }
  134.     if ( root==NULL ) root = sibling;
  135.     else root->_down = sibling;
  136.     va_end(ap);
  137.     return root;
  138. }
  139.  
  140. /* tree duplicate */
  141. ASTBase *
  142. ASTBase::dup()
  143. {
  144.     ASTBase *u, *t=this;
  145.     
  146.     u = new ASTBase;
  147.     *u = *t;
  148.     u->_right = t->_right->dup();
  149.     u->_down = t->_down->dup();
  150.     return u;
  151. }
  152.  
  153. /* tree duplicate */
  154. ASTDoublyLinkedBase *
  155. ASTDoublyLinkedBase::dup()
  156. {
  157.     ASTDoublyLinkedBase *u, *t=this;
  158.     
  159.     if ( t == NULL ) return NULL;
  160.     u = new ASTDoublyLinkedBase;
  161.     *u = *t;
  162.     u->_up = NULL;        /* set by calling invocation */
  163.     u->_left = NULL;
  164.     u->_right = t->_right->dup();
  165.     u->_down = t->_down->dup();
  166.     if ( u->_right!=NULL ) ((ASTDoublyLinkedBase *)u->_right)->_left = u;
  167.     if ( u->_down!=NULL ) ((ASTDoublyLinkedBase *)u->_down)->_up = u;
  168.     return u;
  169. }
  170.  
  171. /*
  172.  * Set the 'up', and 'left' pointers of all nodes in 't'.
  173.  * Initial call is double_link(your_tree, NULL, NULL).
  174.  */
  175. void
  176. ASTDoublyLinkedBase::double_link(ASTBase *left, ASTBase *up)
  177. {
  178.     ASTDoublyLinkedBase *t = this;
  179.  
  180.     t->_left = (ASTDoublyLinkedBase *) left;
  181.     t->_up = (ASTDoublyLinkedBase *) up;
  182.     ((ASTDoublyLinkedBase *)t->_down)->double_link(NULL, t);
  183.     ((ASTDoublyLinkedBase *)t->_right)->double_link(t, up);
  184. }
  185.